#pragma once
#include "../mqcommon/mq_logger.hpp"
#include "../mqcommon/mq_helper.hpp"
#include "../mqcommon/mq_msg.pb.h"

namespace mymq
{
    class Router
    {
    public:
        static bool isLegalRoutingKey(const std::string &routing_key)
        {
            // 合法字符 0-9,a-z,A-Z,.,_组成，只要由这些字符组成即可
            for (auto &k : routing_key)
            {
                if ((k >= '0' && k <= '9') || (k >= 'a' && k <= 'z') || (k >= 'A' && k <= 'Z') || k == '.'||k=='_')
                {
                    continue;
                }
                return false;
            }
            return true;
        }

        static bool isLegalBindingkey(const std::string &binding_key)
        {
            // 1.合法字符 0-9,a-z,A-Z,.，*，#组成
            for (auto &k : binding_key)
            {
                if ((k >= '0' && k <= '9') || (k >= 'a' && k <= 'z') || 
                (k >= 'A' && k <= 'Z') || 
                k == '.' || k == '#' || 
                k == '*'||k=='_')
                {
                    continue;
                }
                return false;
            }
            // 2.*，#必须单独存在
            std::vector<std::string> sub_words;
            StrHelper::split(binding_key, ".", sub_words);
            for (auto &word : sub_words)
            {
                if (word.size() > 1 && (word.find("#") != std::string::npos || word.find("*") != std::string::npos))
                {
                    return false;
                }
            }
            // 3.*与#不能连续出现
            for (int i = 1; i < sub_words.size(); i++)
            {
                if (sub_words[i] == "#" && sub_words[i - 1] == "#")
                    return false;
                if (sub_words[i] == "#" && sub_words[i - 1] == "*")
                    return false;
                if (sub_words[i] == "*" && sub_words[i - 1] == "#")
                    return false;
            }
            return true;
        }
        static bool route(ExchangeType type, const std::string &routing_key, const std::string &binding_key)
        {
            if (type == ExchangeType::DIRECT)
            {
                return (routing_key == binding_key);
            }
            else if (type == ExchangeType::FANOUT)
            {
                return true;
            }
            //主题交换路由
            std::vector<std::string> rout;
            size_t rout_count = mymq::StrHelper::split(routing_key,".",rout);
            std::vector<std::string> bind;
            size_t bind_count = mymq::StrHelper::split(binding_key,".",bind);
            std::vector<std::vector<bool>> dp(bind_count+1,std::vector<bool>(rout_count+1,false));
            dp[0][0]=true;
            //1.如果routing_key以#开头，则将该行的第0列置为1
            for(int i = 1;i<=bind.size();i++)
            {
                if(bind[i-1]=="#")
                {
                    dp[i][0]=true;
                    continue;
                }
                break;
            }
            //2.进行路由匹配
            //如果binding_key中为*，或者该单词与routing_key相同，则匹配成功，继承dp[i-1][j-1]的结果
            //如果binding_key中为#，则该位置的匹配结果为左上dp[i-1][j-1],左dp[i][j-1],上dp[i-1][j]
            for(size_t i = 1;i<=bind_count;i++)
            {
                for(size_t j = 1;j<=rout_count;j++)
                {
                    if((bind[i-1]==rout[j-1])||(bind[i-1]=="*"))
                    {
                        dp[i][j]=dp[i-1][j-1];
                    }
                    else if(bind[i-1]=="#")
                    {
                        dp[i][j] = dp[i-1][j-1] | dp[i][j-1] | dp[i-1][j];
                    }
                }
            }
            return dp[bind_count][rout_count];
        }
        };
    }
